<template>
  <div>
    <div v-if="title" style="margin-top: 10px;">{{title}}</div>
    <!-- 内容 -->
    <div class="weui-uploader__bd" style="float: left;margin-right: 1px;">
      <ul class="weui-uploader__files">
        <!-- 按钮 -->
        <span v-on:click="showMenu" v-if="permission=='w' || permission=='b'" :style="style" :class="cls">
          <div class="weui-uploader__input-box" style="margin-top: 20px;"></div>
        </span>
        <li class="weui-uploader__file oneItem" v-for="file in fileList">
          <!--图片-->
          <img :src="file.src" @click="clickImg(file)" :style="{height:file.type=='file'?'55px':'100%',width:file.type=='file'?'65px':'100%'}"/>

          <!--删除按钮-->
          <van-icon name="cross" v-if="['b','w'].includes(permission)" style="position:relative;left:32px;background-color: rgba(0, 0, 0, .7);border-radius: 0 0 0 11px;color: #fff;padding: 2px;" size="11" @click="del(file)" :style="{top:file.type=='file'?'-67px':'-91px'}" />
          <!-- <x-icon v-if="['b','w'].includes(permission)" style="position:relative;left:40px;fill: rgba(0, 0, 0, .7);" type="ios-close-outline"
                  size="15" @click="del(file)" class="icon-red" :style="{top:file.type=='file'?'-71px':'-95px'}"></x-icon> -->
          <span class="file-name-txt" v-if="file.type=='file'">{{ file.name }}</span>

          <!--下载按钮-->
          <x-button plain mini class="dButton"
                    :style="{top:file.type=='file'||permission=='r'?'-8px':'-29px'}"
                    type="primary" @click.native="download(file)">{{ file.ext }}
          </x-button>
          <a :id="file.id" :href="file.href"></a>
        </li>
      </ul>
    </div>


    <!-- 上传进度 -->
    <loading :show="uploadingFile.active" :text="uploadingFile.statusText"></loading>

    <!-- 选择方式菜单 -->
    <actionsheet v-model="show" :menus="menus" @on-click-menu="click" show-cancel></actionsheet>

    <!-- 上传附件组件 -->
    <file-upload ref="upload" name="file" :input-id="fileUploadId"
                 :extensions="extensions" :accept="accept" capture="camera"
                 v-model="files" :custom-action="customAction" :multiple="true"
                 @input-file="inputFile" @input-filter="inputFilter">
    </file-upload>

    <!-- 预览图片 -->
    <x-dialog v-model="showImg" hide-on-blur>
      <div class="img-box">
        <img :src="showImgUrl" style="max-width:100%"/>
      </div>
    </x-dialog>
  </div>
</template>

<script>

import Vue from 'vue';

const VueUploadComponent = require('vue-upload-component');
Vue.component('file-upload', VueUploadComponent);
import {Popup} from 'vux';

Vue.component('popup', Popup);
import {XButton} from 'vux';

Vue.component('x-button', XButton);
import {Group} from 'vux';

Vue.component('group', Group);
import {Flexbox, FlexboxItem} from 'vux';

Vue.component('flexbox', Flexbox);
Vue.component('flexbox-item', FlexboxItem);
import {XImg} from 'vux';

Vue.component('x-img', XImg);
import {Actionsheet} from 'vux';

Vue.component('actionsheet', Actionsheet);
import {Loading} from 'vux';

Vue.component('loading', Loading);
import common from '@/components/customize/plugins/common.js'

/**
 * <ab-upload v-model="files" :permission="xxx" title="">
 *    <a href="javascript:;" class="weui-btn weui-btn_mini weui-btn_primary fa fa-upload">上传</a>
 * </ab-upload>
 */
export default {
  props: {
    value: {
      default: "[]"
    },
    permission: {},
    extensions: {
      default: ""
    },
    accept: {
      default: ""
    },
    size: {},
    title:""
  },
  data: function () {
    return {
      fileImgUrl: '',
      show: false,
      menus: {
        photo: "拍照",
        file: "选择文件"
      },
      files: [],//上传组件的数组
      fileList: [],//显示已上传成功的图片的数组    （为解决上传多图时，因监听数据变化只能上传一张的问题，把上传组件的参数和显示图片数据的参数分开 2024-4-16）
      fileUploadId: "",
      url: Vue.__ctx + "/sys/sysFile/upload",
      style: {
        border: "",
        cursor: "pointer"
      },
      cls: "",
      showImg: false,
      showImgUrl: "",
      uploadingFile: {},
    }
  },
  mounted: function () {
    this.fileUploadId = "fileId" + Math.random();//随机id
    this.show = false;
    this.handleStyle();
  },
  methods: {
    showMenu: function () {
      this.show = true;
    },
    click: function (key) {
      if (key == "photo") {//拍照
        $(document.getElementById(this.fileUploadId)).attr("capture", "camera");
        $(document.getElementById(this.fileUploadId)).attr("cameraDisable", "false");
        $(document.getElementById(this.fileUploadId)).attr("accept", "image/*");
      }
      if (key == "file") {//文件上传
        $(document.getElementById(this.fileUploadId)).removeAttr("capture");
        $(document.getElementById(this.fileUploadId)).removeAttr("cameraDisable");
        if (this.accept) {
          $(document.getElementById(this.fileUploadId)).attr("accept", this.accept);
        } else {
          $(document.getElementById(this.fileUploadId)).removeAttr("accept");
        }
      }
      //手动发布事件
      var event = document.createEvent('MouseEvents');
      event.initMouseEvent('click', false, false);
      document.getElementById(this.fileUploadId).dispatchEvent(event);
    },
    customAction: async function (file, component) {
      file.file = await common.ImageCompress(file.file)
      file.postAction = this.url;
      // console.log(file)
      component.uploadHtml5 = function (file) {
        var form = new window.FormData();
        form.append(this.name, file.file, file.file.filename || file.name);
        var xhr = new XMLHttpRequest();
        xhr.withCredentials = true;
        xhr.open('POST', file.postAction);
        return this.uploadXhr(xhr, file, form);
      };
      return component.uploadHtml5(file);
    },
    //添加，更新，移除 后
    inputFile: function (newFile, oldFile) {
      // 自动上传
      if (Boolean(newFile) !== Boolean(oldFile) || oldFile.error !== newFile.error) {
        if (!this.$refs.upload.active) {
          this.$refs.upload.active = true
        }
      }
      // 更新文件
      if (newFile && oldFile) {
        this.uploadingFile = newFile;
        // 开始上传
        if (newFile.active && newFile.active !== oldFile.active) {
          newFile.statusText = "开始上传";
        }

        // 上传进度
        if (newFile.progress !== oldFile.progress) {
          newFile.statusText = "上传中..." + newFile.progress + "%";
        }

        // 上传错误
        if (newFile.error !== oldFile.error) {
          newFile.statusText = "上传错误";
        }

        // 上传成功
        if (newFile.success !== oldFile.success) {
          var result = JSON.parse(newFile.response);
          newFile.statusText = result.msg;
          if (result.isOk) {
            newFile.id = result.data;
            newFile.href = Vue.__ctx + "/sys/sysFile/download?fileId=" + result.data;
            // 上传成功后加到显示图片数组里-start  2024-4-16
            var obj = {
              ext: newFile.name.split("\.")[1].toUpperCase(),
              success: true,
              statusText: "已上传",
              href: newFile.href,
              id: newFile.id,
              name: newFile.name
            }
            if (/\.(jpeg|jpe|jpg|gif|png|webp)$/i.test(newFile.name)) {
              obj.src = newFile.href;
              obj.type = "img";
            } else {
              obj.src = this.fileImgUrl;
              obj.type = "file";
            }
            this.fileList.push(obj)
            // 上传成功后加到显示图片数组里-end
          } else {
            Vue.tools.toast(result.msg, "warn");
          }
        }
      }

      // 删除文件
      if (!newFile && oldFile) {
      }
    },
    inputFilter: function (newFile, oldFile, prevent) {
      if (this.extensions && !this.extensions.split(",").includes(newFile.name.split(".")[1])) {
        Vue.tools.toast("仅支持文件类型：" + this.extensions);
        prevent();
        return;
      }

      // 添加文件
      if (newFile && !oldFile) {
        if (this.size && this.files && this.files.length >= this.size) {
          Vue.tools.toast("已达附件上传数量限制：" + this.size);
          prevent();
          return;
        }

        // 创建 `src` 字段 用于缩略图预览
        newFile.src = ''
        let URL = window.URL || window.webkitURL
        if (URL && URL.createObjectURL) {
          if (!/\.(jpeg|jpe|jpg|gif|png|webp)$/i.test(newFile.name)) {
            newFile.src = this.fileImgUrl;
          } else {
            newFile.src = URL.createObjectURL(newFile.file);
          }
        }
      }
    },
    clickImg: function (file) {
      if (file.type == "file") {
        return this.download(file);
      }
      if (!/\.(jpeg|jpe|jpg|gif|png|webp)$/i.test(file.name)) {
        Vue.tools.toast("系统仅支持预览图片");
        return;
      }
      this.showImg = true;
      if (file.href) {
        this.showImgUrl = file.href;
      } else {
        this.showImgUrl = file.src;
      }
    },
    del: function (file) {
      var idx = this.fileList.indexOf(file);
      var that = this;
      if (!file.success) {
        that.fileList.splice(idx, 1);
        that.$refs.upload.remove(file);
        return;
      }
      var url = Vue.__ctx + "/sys/sysFile/del";
      var post = Vue.baseService.postForm(url, {
        fileId: file.id
      });
      Vue.tools.getResultData(post, function () {
        Vue.tools.toast("删除成功");
        that.fileList.splice(idx, 1);
        that.$refs.upload.remove(file);
      });
    },
    download: function (file) {
      //Vue.tools.toast("若无法正常下载附件可在UC等专用浏览器下载（QQ/微信等APP内置浏览器的限制问题）");
      var fileFrame = document.createElement('iframe');
      fileFrame.src = file.href;
      fileFrame.style.display = 'none';
      document.body.appendChild(fileFrame);
    },
    handleStyle: function () {
      if (!this.$vnode.context.$validity) {
        this.$vnode.context.$validity = {};
      }
      if (this.permission == "b") {
        if (!this.value || this.value == "[]") {
          this.$vnode.context.$validity[this.$attrs.desc] = "必填";
          this.cls = "file-valid-error";
        } else {
          delete this.$vnode.context.$validity[this.$attrs.desc];
          this.style["border"] = "";
          this.cls = "";
        }
      }
      //处理值
      this.fileList = JSON.parse(this.value || "[]");
      var that = this;
      this.fileList.forEach(function (file) {
        file.success = true;
        file.statusText = "已上传";
        file.href = Vue.__ctx + "/sys/sysFile/download?fileId=" + file.id;
        if (/\.(jpeg|jpe|jpg|gif|png|webp)$/i.test(file.name)) {
          file.src = file.href;
          file.type = "img";
        } else {
          file.src = that.fileImgUrl;
          file.type = "file";
        }
        file.ext = file.name.split("\.")[1].toUpperCase();
      });
    },
  },
  watch: {
    //数据更新时 在td 下增加按钮
    value: function (newVal, oldVal) {
      if (newVal != oldVal) {
        this.handleStyle();
      }
    },
    fileList: {
      deep: true,
      handler: function (newVal, oldVal) {
        var list = [];
        this.fileList.forEach(function (file) {
          if (!file.success) {
            return;
          }
          list.push({
            id: file.id,
            name: file.name
          });
        });

        this.$emit('input', JSON.stringify(list));
      }
    }
  },
  destroyed: function () {
    delete this.$vnode.context.$validity[this.$attrs.desc];
  },
}
</script>

<style scoped>
.oneItem {
  margin-bottom: 30px;
  margin-top: 8px;
  text-align: center;
}

/*//删除按钮*/
.delBut {
  position: relative;
  left: 40px;
  fill: rgb(255, 0, 0);
}

/*//下载按钮*/
.dButton {
  position: relative;
  width: 79px;
  height: 24px;
  border-radius: 0;
  line-height: 24px;
  border-color: #eee;
  color: #9c9c9c;
}

.fa-upload:before {
  margin-right: 5px;
}

.file-valid-error .weui-uploader__input-box {
  border: 1px solid red;
}

.file-valid-error .weui-uploader__input-box:before {
  color: red;
  background-color: red;
  width: 1px;
}

.file-valid-error .weui-uploader__input-box:after {
  color: red;
  background-color: red;
  height: 1px;
}

.file-valid-error .fa-upload {
  background-color: #fd9191;
}

.file-name-txt {
  display: block;
  text-align: center;
  margin-top: -27px;
  color: #070cff;
  width: 80px;
  z-index: 1;
  text-overflow: ellipsis;
  overflow-x: hidden;
  font-size: 14px;
  float: left;
}

</style>
<style scoped lang="less">
/deep/.van-icon-cross:before {
  content: '\E6A7';
  color: #fff;
}
</style>
